// src/main/java/com/booking/springrestful/service/LargeModelService.java
package com.booking.springrestful.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.booking.springrestful.config.LargeModelConfig;
import lombok.RequiredArgsConstructor;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

@Service
@RequiredArgsConstructor
public class LargeModelService {

    private static final Logger log = LoggerFactory.getLogger(LargeModelService.class);

    private final LargeModelConfig config;

    private static final String DASHSCOPE_API_URL = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation";

    private final OkHttpClient client = new OkHttpClient.Builder()
            .readTimeout(60, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)
            .connectTimeout(10, TimeUnit.SECONDS)
            .build();

    private static final String SYSTEM_PROMPT =
            "你是一位壮锦文化专家，请围绕壮锦纹样的寓意、历史、工艺进行回答。语言简洁、准确、亲切，避免冗长。回答的时候希望可以给出表情丰富内容。";

    public void streamAnswer(String userQuestion, Consumer<String> onChunk) throws IOException {
        if (userQuestion == null || userQuestion.trim().isEmpty()) {
            throw new IllegalArgumentException("用户问题不能为空");
        }

        // ✅ 安全构造 messages（避免 {{}} 匿名类）
        JSONArray messages = new JSONArray();
        JSONObject systemMsg = new JSONObject();
        systemMsg.put("role", "system");
        systemMsg.put("content", SYSTEM_PROMPT);
        messages.add(systemMsg);

        JSONObject userMsg = new JSONObject();
        userMsg.put("role", "user");
        userMsg.put("content", userQuestion.trim());
        messages.add(userMsg);

        // ✅ 安全构造 input 和 parameters
        JSONObject input = new JSONObject();
        input.put("messages", messages);

        JSONObject parameters = new JSONObject();
        parameters.put("incremental_output", true);

        JSONObject requestBody = new JSONObject();
        requestBody.put("model", "qwen-max");
        requestBody.put("input", input);
        requestBody.put("parameters", parameters);

        String requestJson = requestBody.toJSONString();
        log.debug("向 DashScope 发送请求: {}", requestJson);

        Request request = new Request.Builder()
                .url(DASHSCOPE_API_URL)
                .post(RequestBody.create(requestJson, MediaType.get("application/json; charset=utf-8")))
                .header("Authorization", "Bearer " + config.getApiKey())
                .header("Content-Type", "application/json")
                .header("Accept", "text/event-stream")
                .build();

        try (Response response = client.newCall(request).execute()) {
            log.info("DashScope 响应状态码: {}", response.code());

            if (!response.isSuccessful()) {
                String errorMsg = "";
                if (response.body() != null) {
                    try {
                        errorMsg = response.body().string();
                    } catch (Exception e) {
                        errorMsg = "无法读取错误体: " + e.getMessage();
                    }
                } else {
                    errorMsg = response.message();
                }
                log.error("DashScope API 调用失败 [{}]: {}", response.code(), errorMsg);
                throw new IOException("DashScope API 调用失败 [" + response.code() + "]: " + errorMsg);
            }

            ResponseBody body = response.body();
            if (body == null) {
                log.warn("DashScope 返回空 body");
                return;
            }

            log.info("开始读取流式响应...");
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(body.byteStream(), StandardCharsets.UTF_8))) {

                String line;
                int lineCount = 0;
                while ((line = reader.readLine()) != null) {
                    lineCount++;
                    line = line.trim();
                    if (line.isEmpty() || line.startsWith(":")) {
                        continue; // 跳过空行或注释行（如 : ping）
                    }
                    if (line.startsWith("data:")) {
                        String dataStr = line.substring(5).trim(); // 去掉 "data:"
                        if (dataStr.isEmpty()) {
                            continue;
                        }

                        try {
                            JSONObject dataJson = JSON.parseObject(dataStr);
                            JSONObject output = dataJson.getJSONObject("output");
                            if (output != null) {
                                String text = output.getString("text"); // ✅ 关键：用 output.text
                                String finishReason = output.getString("finish_reason");

                                if ("stop".equals(finishReason)) {
                                    log.debug("流式输出结束");
                                    break;
                                }

                                if (text != null && !text.isEmpty()) {
                                    log.debug("接收到增量文本: '{}'", text);
                                    onChunk.accept(text); // 发送给前端
                                }
                            }
                        } catch (Exception e) {
                            log.warn("解析 data 行失败: {}", dataStr, e);
                        }
                    }
                }
                log.info("流式响应读取完成，共 {} 行。", lineCount);
            }
        } catch (IOException e) {
            log.error("调用 DashScope 流式接口时发生 IO 异常", e);
            throw e;
        } catch (Exception e) {
            log.error("调用 DashScope 流式接口时发生未知异常", e);
            throw new IOException("调用异常: " + e.getMessage(), e);
        }
    }
}